#define _CRT_SECURE_NO_WARNINGS

#include "SharedPtr.h"
#include <iostream>
#include <atomic>
#include <memory>
#include <mutex>
#include <thread>
#include <list>
#include <stdlib.h>

using namespace std;


//class A
//{
//public:
//	virtual void func()
//	{
//		cout << "A" << endl;
//	}
//};
//
//class B : public A
//{
//public:
//	int _b = 10;
//
//	void func()
//	{
//		cout << "B" << endl;
//	}
//};
//
//int main()
//{
//	string s = "\r\n";
//	cout << s.size();
//	return 0;
//}

//struct A
//{
//	operator int()
//	{
//		return _a;
//	}
//
//	int _a = 10;
//};
//
//struct B
//{
//	B()
//	{
//
//	}
//	B(int a)
//	{
//		_b = a;
//	}
//
//	int _b = 20;
//};
//
//int main()
//{
//	cout << 123344 << endl;
//	
//	return 0;
//}

class A
{
public:
	A()
	{}

	A(int a)
		:_a(a)
	{}

	~A()
	{}

private:
	int _a = 10;;
};

template<class T>
struct Freefunc
{
	void operator()(T* ptr)
	{
		cout << "free ptr: " << ptr << endl;
		free(ptr);
	}
};

int main()
{
	bit::shared_ptr<A> sp1(new A[2], [](A a) {delete[] a;});
	bit::shared_ptr<int> sp2((int*)malloc(4), Freefunc<int>());
	bit::shared_ptr<FILE>sp3(fopen("test.txt", "w"), [](FILE* ptr) {fclose(ptr);});
	return 0;
}


//class A
//{
//public:
//	A(int a)
//		:_a(a)
//	{}
//
//	~A()
//	{
//		cout << "~A()" << endl;
//	}
//public:
//	int _a;
//};
//
//class Node
//{
//public:
//	Node()
//	{}
//	~Node()
//	{
//		cout << "~Node()" << endl;
//	}
//	int _data = 0;
//	weak_ptr<Node> _next;
//	weak_ptr<Node> _prev;
//
//};
//
//int main()
//{
//
//	shared_ptr<Node>p1(new Node);
//	shared_ptr<Node>p2(new Node);
//
//	cout << p1.use_count() << endl;
//	cout << p2.use_count() << endl;
//	p1->_next = p2;
//	p2->_prev = p1;
//	cout << p1.use_count() << endl;
//	cout << p2.use_count() << endl;
//	//shared_ptr<A> p1(new A(1));
//	
//	//shared_ptr<A> sp = make_shared<A>(1);
//	//cout << sp->_a << endl;
//
//	return 0;
//}


//struct Node
//{
//	Node* _next = nullptr;
//	Node* _prev = nullptr;
//
//	Node()
//	{}
//
//	~Node()
//	{
//		cout << "~Node" << endl;
//	}
//};
//
//int main()
//{
//	std::shared_ptr<Node> sp1(new Node);
//	std::shared_ptr<Node> sp2(new Node);
//
//	cout << sp2.use_count() << endl;
//	sp1->_next = sp2;
//	cout << sp2.use_count() << endl;
//
//	return 0;
//}

//class nocopy
//{
//public :
//	nocopy() {}
//	nocopy(const nocopy&) = delete;
//	const nocopy& operator = (const nocopy&) = delete;
//	~nocopy() {}
//};
//
//class B :public nocopy
//{
//public:
//	B()
//	{}
//
//private:
//	int _b = 10;
//};
//
//int main()
//{
//	B b1;
//	B b2 = b1;
//
//	return 0;
//}

//int gtotal = 0;
//mutex m;
//
//void func(int n, bit::shared_ptr<list<int>> sp)
//{
//	cout << sp.use_count() << endl;
//
//	for (int i = 0; i < n; ++i)
//	{
//		bit::shared_ptr<list<int>> copy1(sp);
//		bit::shared_ptr<list<int>> copy2(sp);
//		bit::shared_ptr<list<int>> copy3(sp);
//
//		m.lock();
//		copy1->emplace_back(i);
//		m.unlock();
//	}
//}
//
//int main()
//{
//
//	bit::shared_ptr<list<int>> sp(new list<int>);
//
//	thread t1(func, 1000000,sp);
//	thread t2(func, 2000000,sp);
//
//	t1.join();
//	t2.join();
//
//	cout << sp->size() << endl;
//	cout << sp.use_count() << endl;
//
//	return 0;
//}









//class A
//{
//public:
//	A()
//	{
//		_a = 10;
//		_b = 20;
//	}
//
//	int _a;
//	int _b;
//};

//shared_ptr
//int main()
//{
//	/*shared_ptr<int> A(new int(1));
//	shared_ptr<int> B(A);*/
//
//	bit::shared_ptr<int> A(new int(1));
//	bit::shared_ptr<int> B(new int(2));
//	{
//		bit::shared_ptr<int> C(A);
//
//		*A = 3;
//	}
//	return 0;
//}

//unique_ptr
//int main()
//{
//	unique_ptr<int[]> up1(new int[10]);
//
//	for (int i = 0;i < 10; ++i)
//	{
//		up1[i] = i + 1;
//	}
//	for (int i = 0;i < 10; ++i)
//	{
//		cout << up1[i] << endl;
//	}
//
//	if(up1)
//		cout << up1.get() << endl;
//
//	unique_ptr<A> up2(new A);
//
//	up2->_a = 20;
//	up2->_b = 30;
//
//	//unique_ptr<A> up3(up2);
//
//
//	return 0;
//}